package com.zed.api.games.answer.show;

import com.zed.api.domain.Identifiable;
import com.zed.api.games.GameException;

import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 题库展示
 *
 * @author Zed
 */
public abstract class AnswerShowWorld implements Serializable, Identifiable<String> {

    @Serial
    private static final long serialVersionUID = 4322350492727380780L;

    private String id;

    private transient int tipsIndex;

    /**
     * 选择的答案
     */
    private List<AlternativeAnswer> alternativeAnswers;

    private CorrectAlternativeAnswer correctAlternativeAnswer;

    /**
     * 提示
     */
    private List<String> tips;

    protected AnswerShowWorld(Builder builder) {
        this.id = Objects.requireNonNull(builder.id, "\"id\" cannot be null.");
        this.alternativeAnswers = Objects.requireNonNull(builder.alternativeAnswers, "\"alternativeAnswers\" cannot be null.");

        for (AlternativeAnswer alternativeAnswer : this.alternativeAnswers) {
            if (alternativeAnswer instanceof CorrectAlternativeAnswer) {
                this.correctAlternativeAnswer = (CorrectAlternativeAnswer) alternativeAnswer;
                break;
            }
        }

        Objects.requireNonNull(this.correctAlternativeAnswer, "\"correctAlternativeAnswer\" cannot be null.");

        this.tips = builder.tips == null ? Collections.emptyList() : Collections.unmodifiableList(builder.tips);
    }


    /**
     * 获取主键
     *
     * @return {@link String}
     */
    @Override
    public String getId() {
        return this.id;
    }

    /**
     * 获取题目:
     * 1.图片类型:  {@link Byte[]}
     * 2.文字: {@link String}
     *
     * @return {@link Object}
     */
    public abstract Object getTheme() throws GameException;

    /**
     * 获取随机选择的答案
     *
     * @return {@link List}
     */
    public List<AlternativeAnswer> getRandomAlternativeAnswers() {
        Collections.shuffle(this.alternativeAnswers);
        return this.alternativeAnswers;
    }

    /**
     * 获取正确答案
     *
     * @return {@link CorrectAlternativeAnswer}
     */
    public CorrectAlternativeAnswer getCorrectAlternativeAnswer() {
        return this.correctAlternativeAnswer;
    }

    /**
     * 获取单个提示
     *
     * @return {@link String}
     */
    public String getOneTips() {
        if (this.tips == null) return null;
        if (this.tipsIndex > this.tips.size() - 1) {
            return null;
        }
        return this.tips.get(this.tipsIndex++);
    }

    public abstract static class Builder {
        private String id;
        private List<AlternativeAnswer> alternativeAnswers;
        private List<String> tips;

        /**
         * 设置唯一主键
         *
         * @param id {@link String}
         * @return {@link Builder}
         */
        public Builder id(String id) {
            this.id = id;
            return this;
        }

        /**
         * 添加答案
         *
         * @param alternativeAnswer {@link AnswerShowWorld}
         * @return {@link Builder}
         */
        public Builder addAlternativeAnswer(AlternativeAnswer alternativeAnswer) {
            if (this.alternativeAnswers == null) {
                this.alternativeAnswers = new ArrayList<>();
            }
            this.alternativeAnswers.add(alternativeAnswer);
            return this;
        }

        /**
         * 添加提示
         *
         * @param tip {@link }
         * @return {@link Builder}
         */
        public Builder addTips(String tip) {
            if (this.tips == null) {
                this.tips = new ArrayList<>();
            }
            this.tips.add(tip);
            return this;
        }

        /**
         * 移除提示
         *
         * @param tip {@link String},提示
         * @return {@link Builder}
         */
        public Builder removeTips(String tip) {
            if (this.tips != null) this.tips.remove(tip);
            return this;
        }

        /**
         * 构建
         *
         * @return {@link AnswerShowWorld}
         */
        public abstract AnswerShowWorld build() throws Exception;

    }


}
